﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XcoAppSpaces.Core;
using XcoAppSpaces.Core.Ports;
using System.Threading;
using NUnit.Framework;

namespace test.XcoAppSpaces.Core
{
	[TestFixture]
	public class testLargeDataTransfer
	{
		[Serializable]
		public class Data
		{
			public byte[] Buffer { get; set; }
			public string Info { get; set; }

			public Data(string info, int bufferLength)
			{
				Info = info;
				Buffer = new byte[bufferLength];
			}

			public Data()
			{
			}
		}

		[Serializable]
		public class Request
		{
			public Port<Data> ReturnPort { get; set; }
			public Request()
			{
				ReturnPort = new Port<Data>();
			}
		}

		public class Contract : Port<Request>
		{
		}

		public class MyServer : Contract
		{
			int _Counter = 0;
			const int _BufferLength = 510000; //Hier mit der Größe spielen

			[XcoConcurrent]
			protected void ProcessComplexMsg(Request msg)
			{
				Data data = new Data(string.Format("Request Nr. {0} => Length={1}", _Counter, _BufferLength), _BufferLength);
				msg.ReturnPort.Post(data);
				Console.WriteLine(string.Format("Request Nr. {0} => Length={1} sent", _Counter, _BufferLength));
				_Counter++;
			}
		}

		[Test]
		public void TestLargeDataPort()
		{
			//int dataSize = 510000;

			using (XcoAppSpace space1 = new XcoAppSpace("tcp.port=4000"),
			                   space2 = new XcoAppSpace("tcp.port=0"))
			{

				int count = 0;
				space1.RunWorker<Contract, MyServer>();
				
				var remoteWorker = space2.ConnectWorker<Contract>(Environment.MachineName + ":4000");
                for (int i = 0; i < 8; i++)
				{
					remoteWorker.Post(
						new Request { ReturnPort = Port.WithReceiver<Data>(data => Interlocked.Increment(ref count)) }, 
						Port.WithReceiver<Exception>(ex => Console.WriteLine("Fehler: " + ex.Message)));
					Thread.Sleep(500);
				}

				Thread.Sleep(1000);
				Assert.AreEqual(8, count);
			}
		}
	}
}
